package cn.stylefeng.guns.modular.gridsystem.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.guns.core.enums.CommonStatusEnum;
import cn.stylefeng.guns.core.exception.ServiceException;
import cn.stylefeng.guns.core.exception.enums.StatusExceptionEnum;
import cn.stylefeng.guns.core.factory.PageFactory;
import cn.stylefeng.guns.core.pojo.page.PageResult;
import cn.stylefeng.guns.modular.gridsystem.constants.SystemConstant;
import cn.stylefeng.guns.modular.gridsystem.entity.BizCollectorConfig;
import cn.stylefeng.guns.modular.gridsystem.entity.BizCollectorConfigTemplate;
import cn.stylefeng.guns.modular.gridsystem.enums.LogExceptionEnum;
import cn.stylefeng.guns.modular.gridsystem.enums.SystemParamExceptionEnum;
import cn.stylefeng.guns.modular.gridsystem.mapper.BizCollectorConfigMapper;
import cn.stylefeng.guns.modular.gridsystem.model.param.BizCollectorConfigParam;
import cn.stylefeng.guns.modular.gridsystem.model.param.BizCollectorConfigTemplateParam;
import cn.stylefeng.guns.modular.gridsystem.model.param.CollectorConfigParam;
import cn.stylefeng.guns.modular.gridsystem.model.result.BizCollectorConfigResult;
import cn.stylefeng.guns.modular.gridsystem.service.BizCollectorConfigService;
import cn.stylefeng.guns.modular.gridsystem.service.BizCollectorConfigTemplateService;
import cn.stylefeng.guns.modular.gridsystem.utils.OptionalBean;
import cn.stylefeng.guns.sys.modular.app.enums.SysAppExceptionEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

/**
 * 8路采集器配置 服务实现类
 *
 * @author ssy
 * @date 2022/02/18 13:58
 */
@Service
public class BizCollectorConfigServiceImpl extends ServiceImpl<BizCollectorConfigMapper, BizCollectorConfig> implements BizCollectorConfigService {
    @Resource
    private BizCollectorConfigTemplateService bizCollectorConfigTemplateService;


    /**
     * 分页查询8路采集器配置
     *
     * @param bizCollectorConfigParam 查询条件入参
     *                                gatewayId          网关id
     * @return PageResult<BizCollectorConfig>
     */
    @Override
    public PageResult<BizCollectorConfig> page(BizCollectorConfigParam bizCollectorConfigParam) {
        OptionalBean.ofNullable(bizCollectorConfigParam).orElseThrow(() -> new ServiceException(SystemParamExceptionEnum.PARAM_NULL_ERROR));
        // 构造条件
        LambdaQueryWrapper<BizCollectorConfig> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ObjectUtil.isNotEmpty(bizCollectorConfigParam.getGatewayId()), BizCollectorConfig::getGatewayId, bizCollectorConfigParam.getGatewayId());
        // 查询分页结果
        return new PageResult<>(page(PageFactory.defaultPage(), queryWrapper));
    }

    /**
     * 条件查询8路采集器配置
     *
     * @param bizCollectorConfigParam 查询条件入参
     *                                gatewayTypeCode    网关类型编码
     *                                code               网关编号
     *                                gatewayId          网关id
     * @return List<BizCollectorConfig>
     */
    @Override
    public List<BizCollectorConfig> list(BizCollectorConfigParam bizCollectorConfigParam) {
        OptionalBean.ofNullable(bizCollectorConfigParam).orElseThrow(() -> new ServiceException(SystemParamExceptionEnum.PARAM_NULL_ERROR));
        // 构造条件
        LambdaQueryWrapper<BizCollectorConfig> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ObjectUtil.isNotEmpty(bizCollectorConfigParam.getGatewayTypeCode()), BizCollectorConfig::getGatewayTypeCode, bizCollectorConfigParam.getGatewayTypeCode());
        queryWrapper.eq(ObjectUtil.isNotEmpty(bizCollectorConfigParam.getCode()), BizCollectorConfig::getCode, bizCollectorConfigParam.getCode());
        queryWrapper.eq(ObjectUtil.isNotEmpty(bizCollectorConfigParam.getGatewayId()), BizCollectorConfig::getGatewayId, bizCollectorConfigParam.getGatewayId());
        return list(queryWrapper);
    }

    /**
     * 新增8路采集器配置
     *
     * @param bizCollectorConfigParam 新增入参
     *                                id                主键id
     *                                configName        名称
     *                                code              编码
     *                                value             值
     *                                status            状态
     *                                remark            备注
     *                                gatewayId         网关id
     *                                gatewayTypeCode   网关类型编码
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(BizCollectorConfigParam bizCollectorConfigParam) {
        // 将dto转为实体
        BizCollectorConfig bizCollectorConfig = new BizCollectorConfig();
        BeanUtil.copyProperties(bizCollectorConfigParam, bizCollectorConfig);
        save(bizCollectorConfig);
    }

    /**
     * 删除
     *
     * @param bizCollectorConfigParam 删除入参
     *                                id            主键id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(BizCollectorConfigParam bizCollectorConfigParam) {
        // 根据id查询实体
        BizCollectorConfigResult bizCollectorConfig = queryBizCollectorConfig(bizCollectorConfigParam);
        // 更新实体
        removeById(bizCollectorConfig.getId());
    }

    /**
     * 编辑8路采集器配置
     *
     * @param bizCollectorConfigParam 编辑入参
     *                                id            主键id
     *                                configName    名称
     *                                code          编码
     *                                value         值
     *                                status        状态
     *                                remark        备注
     *                                gatewayId     网关id
     */
    @Override
    public void edit(BizCollectorConfigParam bizCollectorConfigParam) {
        BizCollectorConfig bizCollectorConfig = new BizCollectorConfig();
        // 请求参数转化为实体
        BeanUtil.copyProperties(bizCollectorConfigParam, bizCollectorConfig);
        updateById(bizCollectorConfig);
    }

    /**
     * 根据id查看详情8路采集器配置
     *
     * @param bizCollectorConfigParam 详情入参
     *                                id    主键id
     * @return BizCollectorConfigResult
     */
    @Override
    public BizCollectorConfigResult detail(BizCollectorConfigParam bizCollectorConfigParam) {
        return queryBizCollectorConfig(bizCollectorConfigParam);
    }

    /**
     * 修改状态（字典 0正常 1停用 2删除）
     *
     * @param bizCollectorConfigParam 修改状态入参
     *                                id        主键id
     *                                status    状态
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changeStatus(BizCollectorConfigParam bizCollectorConfigParam) {
        OptionalBean.ofNullable(bizCollectorConfigParam).orElseThrow(() -> new ServiceException(SystemParamExceptionEnum.PARAM_NULL_ERROR));
        OptionalBean.ofStr(bizCollectorConfigParam.getId());
        OptionalBean.ofStr(bizCollectorConfigParam.getCode());

        // 校验状态在不在枚举值里
        CommonStatusEnum.validateStatus(bizCollectorConfigParam.getStatus());

        // 更新枚举，更新只能更新未删除状态的
        LambdaUpdateWrapper<BizCollectorConfig> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper
                .eq(BizCollectorConfig::getId, bizCollectorConfigParam.getId())
                .and(i -> i.ne(BizCollectorConfig::getStatus, CommonStatusEnum.DELETED.getCode()))
                .set(BizCollectorConfig::getStatus, bizCollectorConfigParam.getStatus());
        boolean update = update(updateWrapper);
        if (!update) {
            throw new ServiceException(StatusExceptionEnum.UPDATE_STATUS_ERROR);
        }
    }

    /**
     * 根据网关id 和网关code  获取 8路采集器配置 值
     *
     * @param gatewayId 网关ID
     * @param code      编码
     * @return String   8路采集器配置 值
     */
    @Override
    public String getByCode(Integer gatewayId, String code) {
        LambdaQueryWrapper<BizCollectorConfig> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BizCollectorConfig::getGatewayId, gatewayId);
        queryWrapper.eq(BizCollectorConfig::getCode, code);
        queryWrapper.last(SystemConstant.SQL_LIMIT);
        BizCollectorConfig one = getOne(queryWrapper);
        return one == null ? null : one.getValue();

    }

    /**
     * 根据code批量新增八路采集器信息
     *
     * @param collectorConfigParam 新增
     *                             List<Map<String,Object>> code入参
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addConfig(CollectorConfigParam collectorConfigParam) {
        List<Map<String, Object>> codes = collectorConfigParam.getCodes();
        if (CollectionUtil.isNotEmpty(codes)) {
            for (Map<String, Object> map : codes) {
                String code = map.get(SystemConstant.CODE).toString();
                BizCollectorConfigTemplateParam bizCollectorConfigTemplateParam = new BizCollectorConfigTemplateParam();
                bizCollectorConfigTemplateParam.setGatewayTypeCode(code);
                List<BizCollectorConfigTemplate> list = bizCollectorConfigTemplateService.list(bizCollectorConfigTemplateParam);
                for (BizCollectorConfigTemplate bizCollectorConfigTemplate : list) {
                    BizCollectorConfigParam bizCollectorConfigParam1 = new BizCollectorConfigParam();
                    bizCollectorConfigParam1.setGatewayId(collectorConfigParam.getGatewayId());
                    bizCollectorConfigParam1.setGatewayTypeCode(bizCollectorConfigTemplate.getGatewayTypeCode());
                    bizCollectorConfigParam1.setCode(bizCollectorConfigTemplate.getCode());
                    List<BizCollectorConfig> configList = list(bizCollectorConfigParam1);
                    if (CollectionUtil.isEmpty(configList)) {
                        continue;
                    }
                    BizCollectorConfigParam bizCollectorConfigParam = getBizCollectorConfigParam(collectorConfigParam, bizCollectorConfigTemplate);
                    BizCollectorConfig bizCollectorConfig = new BizCollectorConfig();
                    BeanUtil.copyProperties(bizCollectorConfigParam, bizCollectorConfig);
                    save(bizCollectorConfig);
                }

            }
        }
    }

    private BizCollectorConfigParam getBizCollectorConfigParam(CollectorConfigParam collectorConfigParam, BizCollectorConfigTemplate bizCollectorConfigTemplate) {
        BizCollectorConfigParam bizCollectorConfigParam = new BizCollectorConfigParam();
        bizCollectorConfigParam.setGatewayId(collectorConfigParam.getGatewayId());
        bizCollectorConfigParam.setGatewayTypeCode(bizCollectorConfigTemplate.getGatewayTypeCode());
        bizCollectorConfigParam.setCode(bizCollectorConfigTemplate.getCode());
        bizCollectorConfigParam.setValue(bizCollectorConfigTemplate.getValue());
        bizCollectorConfigParam.setRemark(bizCollectorConfigTemplate.getRemark());
        bizCollectorConfigParam.setConfigName(bizCollectorConfigTemplate.getConfigName());
        bizCollectorConfigParam.setStatus(bizCollectorConfigTemplate.getStatus());
        return bizCollectorConfigParam;
    }


    /**
     * 校验参数，检查是否存在重复的编码等
     *
     * @param bizCollectorConfigParam 校验参数
     *                                id    主键id
     *                                code  被校验code
     * @param isExcludeSelf           是否排除本身
     *                                true/false
     */
    private void checkParam(BizCollectorConfigParam bizCollectorConfigParam, boolean isExcludeSelf) {
        OptionalBean.ofNullable(bizCollectorConfigParam).orElseThrow(() -> new ServiceException(SystemParamExceptionEnum.PARAM_NULL_ERROR));
        OptionalBean.ofStr(bizCollectorConfigParam.getId());
        OptionalBean.ofStr(bizCollectorConfigParam.getCode());

        // 构建带code的查询条件
        LambdaQueryWrapper<BizCollectorConfig> queryWrapperByCode = new LambdaQueryWrapper<>();
        queryWrapperByCode.eq(BizCollectorConfig::getCode, bizCollectorConfigParam.getCode());

        // 如果排除自己，则增加查询条件主键id不等于本条id
        if (isExcludeSelf) {
            queryWrapperByCode.ne(BizCollectorConfig::getId, bizCollectorConfigParam.getId());
        }
        if (count(queryWrapperByCode) >= SystemConstant.NUM_1) {
            throw new ServiceException(SysAppExceptionEnum.APP_CODE_REPEAT);
        }

    }

    /**
     * 根据id获取8路采集器配置详情
     *
     * @param bizCollectorConfigParam 查询入参
     *                                id    id查询
     * @return BizCollectorConfigResult
     */
    private BizCollectorConfigResult queryBizCollectorConfig(BizCollectorConfigParam bizCollectorConfigParam) {
        OptionalBean.ofNullable(bizCollectorConfigParam).orElseThrow(() -> new ServiceException(SystemParamExceptionEnum.PARAM_NULL_ERROR));
        OptionalBean.ofStr(bizCollectorConfigParam.getId());
        BizCollectorConfig bizCollectorConfig = getById(bizCollectorConfigParam.getId());
        OptionalBean.ofNullable(bizCollectorConfig).orElseThrow(() -> new ServiceException(LogExceptionEnum.NOT_EXISTED));
        BizCollectorConfigResult collectorConfigResult = new BizCollectorConfigResult();
        BeanUtil.copyProperties(bizCollectorConfig, collectorConfigResult);
        return collectorConfigResult;
    }
}
